package ltd.nullpointer.frontend.model.entity.up;

import com.boot2.core.LongBaseEntity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.ToString;
import ltd.nullpointer.frontend.tcp.resolver.parser.SensorSelfNoResolverParser;
import ltd.nullpointer.tcp.core.annotation.DeviceSn;
import ltd.nullpointer.tcp.core.annotation.TcpUpMessage;
import ltd.nullpointer.tcp.core.annotation.TcpUpOffset;
import ltd.nullpointer.tcp.core.constant.TCPEnum;
import ltd.nullpointer.tcp.core.resolver.parser.Height4ToIntResolverParser;
import ltd.nullpointer.tcp.core.resolver.parser.Low4ToIntResolverParser;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;
import org.hibernate.annotations.SQLDelete;
import org.hibernate.annotations.Where;

import javax.persistence.Entity;
import javax.persistence.Table;
import java.math.BigDecimal;
import java.util.Date;

/**
 * @author zhangweilin
 * @Description: 传感器数据
 * @date 2019/12/7
 */
@ApiModel("传感器数据")
@TcpUpMessage(start = 7, messageCode = {"557A10", "557A11"}, uniqueProperties = {"sensorNo", "measuringTime"})
@Data
@ToString(callSuper = true)
@Entity
@Table
@SQLDelete(sql = "update np_biz_sensor_data set is_deleted = id where id = ?")
@Where(clause = "is_deleted is false")
@DynamicInsert // 加上此注解，可以只添加有值的字段
@DynamicUpdate // 此注解，是指，会先查，然后跟参数对比，不一样的就更新，所以并不是有值更新，如果db中有值，参数里没值，那么db中的值会清空
public class SensorData extends LongBaseEntity {

    /**
     * 传感器编号
     */
    @ApiModelProperty("传感器编号")
    @TcpUpOffset(start = 1, end = 8)
    @DeviceSn
    private String sensorNo;

    /**
     * 传感器自编号
     */
    @ApiModelProperty("传感器自编号")
    @TcpUpOffset(start = 30, end = 45, resolveType = TCPEnum.ResolveType.ascii)//, resolverParser = SensorSelfNoResolverParser.class)
    private String sensorSelfNo;

    /**
     * 传感器型号
     */
    @ApiModelProperty("传感器型号")
    @TcpUpOffset(start = 46, end = 53, resolveType = TCPEnum.ResolveType.ascii)
    private String model;

    /**
     * 测量时间
     */
    @ApiModelProperty("测量时间")
    @TcpUpOffset(start = 9, end = 14, dateFormat = "yyMMddHHmmss")
    private Date measuringTime;

    @ApiModelProperty("测量日期")
    private Date measuringDate;

    /**
     * 温度
     */
    @ApiModelProperty("测量温度")
    @TcpUpOffset(start = 15, end = 16, calcExpression = "this*0.1M", resolveType = TCPEnum.ResolveType.hexByte2UnsignedInt)
    private BigDecimal temp;

    /**
     * 测量值, type为最底下那个属性，也需要被解析
     */
    @ApiModelProperty("测量值")
    @TcpUpOffset(start = 17, end = 18, calcExpression = "this/math.pow(10, num)", resolveType = TCPEnum.ResolveType.hexByte2Int)
    private BigDecimal measurement;

    /**
     * 测量值  //todo 麻烦上报个报文调试一下，此新增的字段不确定是否对解析有影响，忘了是否有判断了，按理没有TcpUpOffset注解的，在解析时直接忽略
     */
    @ApiModelProperty(value = "测量值(原始的)")
    private BigDecimal originalMeasure;

    /**
     * 偏移值
     */
    @ApiModelProperty("偏移值")
    @TcpUpOffset(start = 19, end = 20, calcExpression = "this/math.pow(10, num)", resolveType = TCPEnum.ResolveType.hexByte2Int)
    private BigDecimal deviation;

    /**
     * 传感器应变频率
     */
    @ApiModelProperty("传感器应变频率")
    @TcpUpOffset(start = 21, end = 22, calcExpression = "this*0.1M", resolveType = TCPEnum.ResolveType.hexByte2Int)
    private BigDecimal strainFre;

    /**
     * 传感器补偿频率
     */
    @ApiModelProperty("传感器补偿频率")
    @TcpUpOffset(start = 23, end = 24, calcExpression = "this*0.1M", resolveType = TCPEnum.ResolveType.hexByte2Int)
    private BigDecimal comFre;

    /**
     * 传感器应变单位
     */
    @ApiModelProperty("传感器应变单位")
    @TcpUpOffset(start = 25, end = 28, resolveType = TCPEnum.ResolveType.ascii)
    private String unit;

    /**
     * 传感器类型(小数点位)
     */
    @ApiModelProperty("小数点位,取该字节高四位")
//    @TcpUpOffset(start = 29, end = 29, resolverParser = {Height4ToIntResolverParser.class, SensorDataCalcDecimalResolverParser.class})
    @TcpUpOffset(start = 29, end = 29, repeat = true, resolverParser = Height4ToIntResolverParser.class)
    private Integer num;

    @ApiModelProperty("传感器类型,取该字节低四位")
//    @TcpUpOffset(start = 29, end = 29, resolverParser = {Height4ToIntResolverParser.class, SensorDataCalcDecimalResolverParser.class})
    @TcpUpOffset(start = 29, end = 29, resolverParser = Low4ToIntResolverParser.class)
    private Integer type;

    public void setMeasuringTime(Date measuringTime) {
        this.measuringTime = measuringTime;
        this.measuringDate = measuringTime;
    }
}